package com.mxpio.erp.common.order.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums.BpmnStatus;
import com.mxpio.erp.common.enums.OrderStatusEnums.CloseStatus;
import com.mxpio.erp.common.enums.OrderStatusEnums.OrderStatus;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.policy.OrderContext;
import com.mxpio.erp.common.order.policy.OrderPolicy;
import com.mxpio.erp.common.order.provider.OrderContextProvider;
import com.mxpio.erp.common.order.service.OrderService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.impl.BaseServiceImpl;

/**
 * 订单统一执行操作
 * @author mxpio
 *
 */
@Service
public class OrderServiceImpl extends BaseServiceImpl<Order> implements OrderService {
	
	@Autowired(required = false)
	private List<OrderContextProvider> orderContextProviders;


	/**
	 * 单据执行
	 */
	@Override
	@Transactional(readOnly = false)
	public OrderContext execute(Order order, OrderPolicy policy) {
		
		// 通用OrderContext初始化
		OrderContext context = OrderContext.init(order);
		policy.config(context);
		// 遍历匹配的 Context提供器 补充Context信息
		if(CollectionUtils.isNotEmpty(orderContextProviders)){
			for(OrderContextProvider provider : orderContextProviders){
				if(provider.supports(order.getClass())){
					provider.provide(context);
				}
			}
		}
		if(CollectionUtils.isEmpty(context.getErrors())){
			// 执行订单
			policy.apply(context);
		}
		
		return context;
	}
	
	@Override
	@Transactional(readOnly = false)
	public Result<Order> updateBpmnStatus(Order bizOrder, BpmnStatus bpmnStatus) {
		bizOrder.setBpmnStatus(bpmnStatus.getStatusCode());
		bizOrder.setReviewer(SecurityUtils.getLoginUsername());
		bizOrder.setReviewTime(new Date());
        this.update(bizOrder);
        return Result.OK();
	}

	@Override
	@Transactional(readOnly = false)
	public Result<Order> updateCloseStatus(Order bizOrder, CloseStatus closeStatus) {
		if(CloseStatus.CLOSED.equals(closeStatus) && bizOrder.getCloseStatus().equals(OrderStatusEnums.CloseStatus.CLOSED.getStatusCode())){
			return Result.error("非打开状态不可关闭");
		}else if(CloseStatus.OPEN.equals(closeStatus) && bizOrder.getCloseStatus().equals(OrderStatusEnums.CloseStatus.OPEN.getStatusCode())){
			return Result.error("非关闭状态不可打开");
		}
		bizOrder.setCloseStatus(closeStatus.getStatusCode());
        this.update(bizOrder);
        return Result.OK(bizOrder);
	}

	@Override
	@Transactional(readOnly = false)
	public Result<? extends Order> updateOrderStatus(Order bizOrder, OrderStatus orderStatus) {
		bizOrder.setOrderStatus(orderStatus.getStatusCode());
        this.update(bizOrder);
        return Result.OK(bizOrder);
	}


}
